package com.ys.nms.module.business.service.linksManual;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fhs.core.trans.anno.TransMethodResult;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ys.nms.module.business.dal.dataobject.devices.DevicesDO;
import com.ys.nms.module.business.dal.dataobject.ports.PortsDO;
import com.ys.nms.module.business.dal.dataobject.portsVlans.PortsVlansDO;
import com.ys.nms.module.business.dal.mysql.companyproperty.CompanyPropertyMapper;
import com.ys.nms.module.business.libreApi.devices.LibreNmsDeviceClient;
import com.ys.nms.module.business.service.devices.DevicesService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import com.ys.nms.module.business.controller.admin.linksManual.vo.*;
import com.ys.nms.module.business.dal.dataobject.linksManual.LinksManualDO;
import com.ys.nms.framework.common.pojo.PageResult;
import com.ys.nms.framework.common.pojo.PageParam;
import com.ys.nms.framework.common.util.object.BeanUtils;

import com.ys.nms.module.business.dal.mysql.linksManual.LinksManualMapper;

import static com.ys.nms.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.ys.nms.framework.common.util.collection.CollectionUtils.convertList;
import static com.ys.nms.framework.common.util.collection.CollectionUtils.diffList;
import static com.ys.nms.module.business.enums.ErrorCodeConstants.*;

/**
 * 线路-手动 Service 实现类
 *
 * @author zzy
 */
@Service
@Validated
@RequiredArgsConstructor
public class LinksManualServiceImpl implements LinksManualService {

    private final LibreNmsDeviceClient deviceClient;

    @Resource
    private LinksManualMapper linksManualMapper;


    @Resource
    private DevicesService devicesService;


    @Override
    public Integer createLinksManual(LinksManualSaveReqVO createReqVO) {
        // 插入
        LinksManualDO linksManual = BeanUtils.toBean(createReqVO, LinksManualDO.class);
        linksManualMapper.insert(linksManual);

        // 返回
        return linksManual.getId();
    }

    @Override
    public void updateLinksManual(LinksManualSaveReqVO updateReqVO) {
        // 校验存在
        validateLinksManualExists(updateReqVO.getId());
        // 更新
        LinksManualDO updateObj = BeanUtils.toBean(updateReqVO, LinksManualDO.class);
        linksManualMapper.updateById(updateObj);
    }

    @Override
    public void deleteLinksManual(Integer id) {
        // 校验存在
        validateLinksManualExists(id);
        // 删除
        linksManualMapper.deleteById(id);
    }

    @Override
    public void deleteLinksManualListByIds(List<Integer> ids) {
        // 删除
        linksManualMapper.deleteByIds(ids);
    }


    private void validateLinksManualExists(Integer id) {
        if (linksManualMapper.selectById(id) == null) {
            throw exception(LINKS_MANUAL_NOT_EXISTS);
        }
    }

    @Override
    public LinksManualDO getLinksManual(Integer id) {
        return linksManualMapper.selectById(id);
    }

    @Override
    public PageResult<LinksManualDO> getLinksManualPage(LinksManualPageReqVO pageReqVO) {
        return linksManualMapper.selectPage(pageReqVO);
    }

    @Override
    @TransMethodResult
    public List<LinksManualDO> getLinksManualList(LinksManualPageReqVO pageReqVO) {

        List<LinksManualDO>  resultList =  linksManualMapper.selectJoinList(LinksManualDO.class,
                new MPJLambdaWrapper<LinksManualDO>()
                        .selectAll(LinksManualDO.class) // 查询 links_manual 所有字段

                        // 第一次左连接：local_port_id -> ports
                        .leftJoin(PortsDO.class, PortsDO::getPortId, LinksManualDO::getLocalPortId)
                        .selectAs(PortsDO::getIfName, LinksManualDO::getLocalPortName) // 映射本地端口名

                        // 第二次左连接：remote_port_id -> ports
                        .leftJoin(PortsDO.class, PortsDO::getPortId, LinksManualDO::getRemotePortId)
                        .selectAs(PortsDO::getIfName, LinksManualDO::getRemotePortName) // 映射远端端口名

                        // 第三次左连接：remote_port_id -> ports
                        .leftJoin(DevicesDO.class, DevicesDO::getDeviceId, LinksManualDO::getRemoteDeviceId)
                        .selectAs(DevicesDO::getIcon, LinksManualDO::getRemoteIcon) // 映射图标
                        .selectAs(DevicesDO::getHostname, LinksManualDO::getRemoteHostname) // 映射hostname

                        // 第四次左连接：remote_port_id -> ports
                        .leftJoin(DevicesDO.class, DevicesDO::getDeviceId, LinksManualDO::getLocalDeviceId)
                        .selectAs(DevicesDO::getHostname, LinksManualDO::getLocalDeviceName) // 映射图标

                        // 第四次左连接：remote_port_id -> ports
                        .leftJoin(DevicesDO.class, DevicesDO::getDeviceId, LinksManualDO::getRemoteDeviceId)
                        .selectAs(DevicesDO::getHostname, LinksManualDO::getRemoteDeviceName) // 映射图标

                        // 条件放在最后（可读性更好）
                        .eq(LinksManualDO::getLocalDeviceId, pageReqVO.getLocalDeviceId())
                        .eq(LinksManualDO::getActive, 1)

        );


        return resultList;
    }

}